package com.paic.mhis.hcpms.common.validator;

import java.util.ArrayList;
import java.util.List;

import com.paic.pafa.app.biz.bo.validation.DefaultValidStatus;
import com.paic.pafa.app.biz.bo.validation.ValidStatus;
import com.paic.pafa.app.biz.bo.validation.Validator;

/**
 * Validator的链式验证 validatorAll=false , 则发生第一个错误时就退出后面的验证，否则验证全部
 * 支持添加ValidatorList,实现组合 要求验证对象线程安全，不能在运行时添加规则，除非是每次New
 * 
 * @author wh
 * @date 2014/5/22
 */

public class ValidatorList implements Validator
{

	private List<Validator> validators = new ArrayList<Validator>();

	/**
	 * 判断标志：发生错误时，是否继续验证全部规则 (true继续验证,false中止验证)
	 */
	private boolean validateAll = false;

	@Override
	public ValidStatus validate(Object fieldMap)
	{
		ValidStatus all = new DefaultValidStatus();
		validate(fieldMap, all);
		
		return all;
	}

	private void validate(Object fieldMap, ValidStatus all)
	{
		for(Validator tmpValidator : validators)
		{
			ValidStatus tmpValidStatus = tmpValidator.validate(fieldMap);
			merge(all, tmpValidStatus);
			if(!validateAll && tmpValidStatus.isError())
			{
				break;
			}
		}

	}
	
	private void merge(ValidStatus all, ValidStatus validStatus)
	{
		if(validStatus != null && validStatus.isError())
		{
			List<ErrorEntry> errs = validStatus.getErrors();
			for(ErrorEntry entry : errs)
			{
				all.addError(entry);
			}
		}

	}

	/**
	 * <p>
	 * 是否全部验证
	 * </p>
	 * 
	 * @return boolean
	 */
	public boolean isValidateAll()
	{
		return validateAll;
	}

	/**
	 * <p>
	 * 设置是否全部验证
	 * </p>
	 * 
	 * @param validateAll
	 *            void
	 */
	public void setValidateAll(boolean validateAll)
	{
		this.validateAll = validateAll;
	}

	/**
	 * <p>
	 * 添加校验
	 * </p>
	 * 
	 * @param vs
	 *            void
	 */
	public void add(Validator vd)
	{
		validators.add(vd);
	}
	
	/**
	 * <p>
	 * 清空校验器
	 * </p>
	 * 
	 * @param vs
	 *            void
	 */
	public void clean()
	{
		validators.clear();
	}

	/**
	 * <p>
	 * 连续append: validatorList.append(validator1).append(validator2)...
	 * </p>
	 * 
	 * @param vd
	 * @return Validator
	 */
	public Validator append(Validator vd)
	{
		add(vd);
		return this;
	}
}
